#include "stdafx.h"	
#include "Client.h"

////////////////////////
//Forward declarations//
////////////////////////
//Alarm methods
void DoAlarmClient();

//Patient methods
void DoPatientClient(Network::INET_Addr *address, Network::SOCK_Stream *serverStream, Network::SOCK_Connector *connector);
std::string GetPatientInfo();
char* SerializePatientMessage(std::string cpr, u_int *buffer_size);

//Generic methods
int sendDataToServer(Network::INET_Addr *address, Network::SOCK_Stream *serverStream, Network::SOCK_Connector *connector, char* buffer, u_int buffer_size);

// Main method
 int _tmain(int argc, TCHAR *argv[]) 
{
	WSADATA wsaData;	
	int wsResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (wsResult != 0) {
		cout << "WSAStartup failed with error: "<< wsResult <<"\n";		
		return -1;
	}

	//unsigned int port =  DEFAULT_PORT; //log port
	//Network::INET_Addr *address = new Network::INET_Addr(DEFAULT_SERVER, port);
	//Network::SOCK_Stream *serverStream = new Network::SOCK_Stream();
	//Network::SOCK_Connector *connector = new Network::SOCK_Connector();

	//DoPatientClient(address, serverStream, connector);
	DoAlarmClient();
	
	WSACleanup();
	system("pause");
}

void DoAlarmClient()
{
	// send alarms
	for(int i = 0; i <= 10; i++) {
		//RECREATE CONNECTION FOR EACH CLIENT MESSAGE - FOR TESTING
		Network::INET_Addr *address = new Network::INET_Addr(DEFAULT_SERVER, DEFAULT_PORT);
		Network::SOCK_Stream *serverStream = new Network::SOCK_Stream();
		Network::SOCK_Connector *connector = new Network::SOCK_Connector();

		AlarmEvent event;
		event.priority = (u_char)(rand() % 10 + 1); // random number between 1 and 10
		
		event.text = "AlarmEvent no.: ";

		char i_string[8];
		sprintf_s(i_string, "%d", i);

		event.text.append(i_string);
		event.text.append(" ; It works!");

		u_int buffer_size = getAlarmBufferSize(event);
		char* buffer = (char*) malloc(buffer_size);
		
		if (serializeAlarmEvent(event, buffer) != 0) {
			fprintf(stdout, "Error while serializing !\n");		
		}

		int bytesSent = sendDataToServer(address, serverStream, connector, buffer, buffer_size);

		if(bytesSent > 0){
			printf("Data sent to the server: Size = %d; Priority = %d; Text = %s\n", buffer_size, event.priority, event.text.c_str());
		}

		free(buffer);

		free(address);
		free(serverStream);
		free(connector);
	}
}

void DoPatientClient(Network::INET_Addr *address, Network::SOCK_Stream *serverStream, Network::SOCK_Connector *connector)
{
	// send patient events
	std::string cpr = GetPatientInfo();

	//we save the actual buffer_size in the SerializePatientMessage
	u_int buffer_size = -1;
	char* buffer = SerializePatientMessage(cpr, &buffer_size);
	int bytesSent = sendDataToServer(address, serverStream, connector, buffer, buffer_size);

	free(buffer);
}

std::string GetPatientInfo()
{
	cout << "Client has started\n";
	cout << "Please enter a CPR number of a patient: ";

	std::string cpr;

	cin >> cpr;
	if (cpr.size() != 10) {
		cout << "Patient CPR invalid, exiting.\n";
		exit(-1);
	}

	return "";
}

char* SerializePatientMessage(std::string cpr, u_int *buffer_size)
{
	PatientEvent event;
	event.type = rand() % 10 + 1; // random number between 1 and 10
	event.value = cpr;
	(*buffer_size) = getPatientBufferSize(event);
	char* buffer = (char*) malloc((*buffer_size));
	//ZeroMemory(buffer, buffer_size);

	if (serializePatientEvent(event, buffer) != 0) {
		cout << "Error while serializing !\n";		
	}

	return buffer;
}

int sendDataToServer(Network::INET_Addr *address, Network::SOCK_Stream *serverStream, Network::SOCK_Connector *connector, 
					  char* buffer, u_int buffer_size)
{
	int bytesSent = -1;
	bool connected = connector->connect_to_server(*serverStream, *address);

	if (connected)
	{
		cout << "Connected to the server" << endl;

		//printf("Sleeping zzZ (giving server some time)\n");
		//Sleep(100);
		
		//system("pause");

		bytesSent = serverStream->send(buffer, buffer_size, 0);
		//printf("Data sent to the server. Size = %d\n", bytesSent);
		//cout << ""<< bytesSent << " content = " << buffer << endl;
		
		char rcvBuffer[64];
		ZeroMemory(rcvBuffer, sizeof(rcvBuffer));		
		// TODO the server needs to send information on how large the incoming buffer is
		// we do this on the server, in SelectReactor.cpp line 70.
		//cout << "Waiting to receive from server.\n";
		//serverStream->receive(rcvBuffer, 64, 0);
		//cout << "Data received from server. \nRaw buffer: " << rcvBuffer << endl;

		serverStream->close();
		cout << "Stream closed" << endl;
	} else {
		cout << "Failed connecting. \n";
		int error = WSAGetLastError();
		cout << "WSA error: "<< error <<"\n";
	}

	return bytesSent;
}